package com.lingnan.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lingnan.dto.ChatMessageDTO;
import com.lingnan.entity.po.ChatMessage;
import com.lingnan.mapper.UserAccountMapper;
import com.lingnan.service.ChatMessageService;
import jakarta.annotation.Resource;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
public class ChatWebSocketHandler extends TextWebSocketHandler {

    private static final Map<Long, WebSocketSession> userSessions = new ConcurrentHashMap<>();

    @Resource
    private ObjectMapper objectMapper;
    private ChatMessageService chatMessageService;

    @Lazy
    @Autowired
    public void setChatMessageService(ChatMessageService chatMessageService) {
        this.chatMessageService = chatMessageService;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        Long userId = getUserIdFromSession(session);
        Integer userType = getSenderType(session);
        userSessions.put(userId, session);
        log.info("用户连接: {}", userId);
        // 发送未读消息通知
        session.getAttributes().put("userTypeCache", userType);
        sendUnreadNotification(userId, userType);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        try {
            ChatMessageDTO dto = objectMapper.readValue(message.getPayload(), ChatMessageDTO.class);
            Long senderId = getUserIdFromSession(session);
            chatMessageService.sendMessage(dto, senderId, getSenderType(session));
        } catch (Exception e) {
            log.error("消息处理错误", e);
        }
    }

    private void sendUnreadNotification(Long userId, Integer userType) {
        int unreadCount = chatMessageService.getUnreadCount(userId, userType);
        if (unreadCount > 0) {
            sendMessage(userId, Map.of("type", "unread", "count", unreadCount));
        }
    }

    private Long getUserIdFromSession(WebSocketSession session) {
        try {
            // 从WebSocket连接的查询参数中获取userId
            String query = session.getUri().getQuery();
            if (query != null && query.contains("userId=")) {
                String[] params = query.split("&");
                for (String param : params) {
                    if (param.startsWith("userId=")) {
                        return Long.parseLong(param.split("=")[1]);
                    }
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    private Integer getSenderType(WebSocketSession session) {
        try {
            // 从WebSocket连接的查询参数中获取userType
            String query = session.getUri().getQuery();
            if (query != null && query.contains("userType=")) {
                String[] params = query.split("&");
                for (String param : params) {
                    if (param.startsWith("userType=")) {
                        return Integer.parseInt(param.split("=")[1]);
                    }
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        Long userId = getUserIdFromSession(session);
        if (userId != null) {
            userSessions.remove(userId);
            log.info("用户断开连接: {}", userId);
        }
    }

    public void sendMessage(Long userId, Object message) {
        try {
            WebSocketSession session = userSessions.get(userId);
            if (session != null && session.isOpen()) {
                String json = objectMapper.writeValueAsString(message);
                session.sendMessage(new TextMessage(json));
            }
        } catch (Exception e) {
            log.error("消息发送失败", e);
        }
    }

    public void sendWithdrawNotice(ChatMessage message) {
        Map<String, Object> notice = new HashMap<>();
        notice.put("type", "withdraw");
        notice.put("messageId", message.getId());
        notice.put("sessionId", message.getSessionId());

        // 新增撤回消息内容
        notice.put("content", "[该消息已被撤回]");
        notice.put("senderId", message.getSenderId());
        notice.put("createdAt", new Date());

        // 通知接收者
        sendMessage(message.getReceiverId(), notice);
        // 通知发送者
        sendMessage(message.getSenderId(), notice);
    }
}